package com.usian.wemedia.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.usian.common.constants.message.NewsAutoScanConstants;
import com.usian.model.admin.dtos.NewsAuthDto;
import com.usian.model.base.BaseServiceImpl;
import com.usian.model.common.dtos.PageResponseResult;
import com.usian.model.common.dtos.ResponseResult;
import com.usian.model.common.enums.AppHttpCodeEnum;
import com.usian.model.media.dtos.WmNewsDto;
import com.usian.model.media.dtos.WmNewsPageReqDto;
import com.usian.model.media.pojos.WmNews;
import com.usian.model.media.pojos.WmNewsMaterial;
import com.usian.model.media.pojos.WmUser;
import com.usian.model.media.vo.WmNewsVo;
import com.usian.utils.threadlocal.UserIdThreadLocalUtils;
import com.usian.wemedia.constants.WemediaContans;
import com.usian.wemedia.mapper.WmMaterialMapper;
import com.usian.wemedia.mapper.WmNewsMapper;
import com.usian.wemedia.mapper.WmNewsMaterialMapper;
import com.usian.wemedia.mapper.WmUserMapper;
import com.usian.wemedia.service.WmNewsService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.concurrent.ListenableFuture;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class WmNewsServiceImpl extends BaseServiceImpl<WmNewsMapper, WmNews> implements WmNewsService {


    @Value("${file.url}")
    private String fileServerUrl;

    @Autowired
    private WmNewsMaterialMapper wmNewsMaterialMapper;

    @Autowired
    private WmMaterialMapper wmMaterialMapper;

    @Autowired
    private WmNewsMapper wmNewsMapper;

    @Autowired
    private WmUserMapper wmUserMapper;

    @Autowired
    private KafkaTemplate kafkaTemplate;

    @Override
    public ResponseResult findAll(WmNewsPageReqDto dto) {
        if (dto == null) return errorParam;
        Integer userId = UserIdThreadLocalUtils.getUserId();
        if (userId == null) return needLogin;
        LambdaQueryWrapper<WmNews> wrapper = new LambdaQueryWrapper<>();
        ResponseResult pageData = getPageData(dto, wrapper.eq(WmNews::getUserId, userId).
                eq(dto.getStatus() != null, WmNews::getStatus, dto.getStatus()).
                eq(dto.getChannelId() != null, WmNews::getChannelId, dto.getChannelId()).
                like(dto.getKeyword() != null, WmNews::getTitle, dto.getKeyword()).
                between(dto.getBeginPubDate() != null && dto.getEndPubDate() != null,
                        WmNews::getPublishTime, dto.getBeginPubDate(), dto.getEndPubDate()).orderByDesc(WmNews::getCreatedTime));

        pageData.setHost(fileServerUrl);

        return pageData;
    }

    @Transactional
    @Override
    public ResponseResult submitNews(WmNewsDto dto) {
        if (dto == null) return errorParam;
        Integer userId = UserIdThreadLocalUtils.getUserId();
        if (userId == null) return needLogin;
        WmNewsMaterial wmNewsMaterial = new WmNewsMaterial();
        List<String> images = new ArrayList<>();
        WmNews wmNews = new WmNews();
        //将参数复制到对象中
        BeanUtils.copyProperties(dto, wmNews);
        wmNews.setUserId(userId);
        wmNews.setStatus(dto.getStatus());
        if (dto.getId() == null) {
            fillNews(dto, wmNews, images);
            wmNews.setCreatedTime(new Date());
            //保存文章表信息
            save(wmNews);
            wmNewsMaterial.setNewsId(wmNews.getId());
            reserve(dto, wmNewsMaterial, images);
        } else {
            wmNewsMaterialMapper.deleteByNewsId(dto.getId());
            fillNews(dto, wmNews, images);
            updateById(wmNews);
            wmNewsMaterial.setNewsId(wmNews.getId());
            reserve(dto, wmNewsMaterial, images);
        }
        kafkaTemplate.send(NewsAutoScanConstants.WM_NEWS_AUTO_SCAN_TOPIC, JSON.toJSONString(wmNews.getId()));

        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }


    @Override
    public ResponseResult findWmNewsById(Integer id) {
        if (id == null) return errorParam;
        if (UserIdThreadLocalUtils.getUserId() == null) return needLogin;

        //2.查询数据
        WmNews wmNews = getById(id);
        if (wmNews == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST, "文章不存在");
        }

        //3.结果返回
        ResponseResult responseResult = ResponseResult.okResult(wmNews);
        responseResult.setHost(fileServerUrl);
        return responseResult;
    }


    @Transactional
    @Override
    public ResponseResult delNews(Integer id) {
        if (id == null) return errorParam;
        WmNews wmNews = getById(id);
        if (wmNews.getStatus().equals(WmNews.Status.PUBLISHED.getCode()) && wmNews.getEnable() == 1)
            return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST, "文章已发布，不能删除");
        //4.去除素材与文章的关系
        wmNewsMaterialMapper.delete(Wrappers.<WmNewsMaterial>lambdaQuery().eq(WmNewsMaterial::getNewsId, wmNews.getId()));
        removeById(id);
        return success;
    }

    /*
    * 文章上下架
    * */
    @Override
    public ResponseResult downOrUp(WmNewsDto dto) {
        if (dto == null || dto.getId() == null) return errorParam;
        WmNews wmNews = getById(dto.getId());
        if (wmNews == null) return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST, "文章不存在");
        //判断文章是否发布
        if (!wmNews.getStatus().equals(WmNews.Status.PUBLISHED.getCode())) {
            return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST, "当前文章不是发布状态，不能上下架");
        }


        boolean update = update(Wrappers.<WmNews>lambdaUpdate().eq(WmNews::getId, dto.getId()).set(WmNews::getEnable, dto.getEnable()));
        if (update){
            //4.修改文章状态，同步到app端
            Map<String, Object> mesMap = new HashMap<>();
            if (dto.getEnable() != null && dto.getEnable() > -1 && dto.getEnable() < 2) {
                if (wmNews.getArticleId() != null) {
                    mesMap.put("enable", dto.getEnable());
                    mesMap.put("articleId", wmNews.getArticleId());
                }
            }
            kafkaTemplate.send(NewsAutoScanConstants.WM_NEWS_UP_OR_DOWN_TOPIC,JSON.toJSONString(mesMap));
        }
        return success;
    }

    @Override
    public ResponseResult updateWmNews(WmNews wmNews) {
        if (wmNews==null || wmNews.getId() == null)return errorParam;
        if (getById(wmNews.getId()) == null) return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST, "文章不存在");
        boolean b = updateById(wmNews);
        if (b){
            return success;
        }
        return saveFailed;
    }

    @Override
    public List<Integer> findRelease() {
        LambdaQueryWrapper<WmNews> wrapper = Wrappers.<WmNews>lambdaQuery();
        List<WmNews> lt = list (wrapper.eq(WmNews::getStatus, 8).lt(WmNews::getPublishTime, new Date()).
                or().eq(WmNews::getStatus, 4).lt(WmNews::getPublishTime, new Date()));
        return lt.stream().map(WmNews::getId).collect(Collectors.toList());
    }

    @Override
    public ResponseResult findList(NewsAuthDto dto) {

        //设置起始页
        dto.setPage((dto.getPage()-1)*dto.getSize());
        dto.setTitle("%"+dto.getTitle()+"%");

        //2.分页查询
        List<WmNewsVo> list = wmNewsMapper.findListAndPage(dto);
        //统计多少条数据
        int count = wmNewsMapper.findListCount(dto);

        //3.结果返回
        PageResponseResult responseResult = new PageResponseResult(dto.getPage(),dto.getSize(),count);
        responseResult.setHost(fileServerUrl);
        responseResult.setData(list);
        return responseResult;
    }

    @Override
    public WmNewsVo findWmNewsVo(Integer id) {

        //1.查询文章信息
        WmNews wmNews = getById(id);
        //2.查询作者
        WmUser wmUser = null;
        if(wmNews!=null && wmNews.getUserId() != null){
            wmUser = wmUserMapper.selectById(wmNews.getUserId());
        }

        //3.封装vo信息返回
        WmNewsVo wmNewsVo = new WmNewsVo();
        BeanUtils.copyProperties(wmNews,wmNewsVo);
        if(wmUser != null){
            wmNewsVo.setAuthorName(wmUser.getName());
        }
        return wmNewsVo;

    }


    /*
     * 保存中间表关联关系
     * */
    private void reserve(WmNewsDto dto, WmNewsMaterial wmNewsMaterial, List<String> images) {

        //关联封面图与素材的关系
        if (dto.getImages() != null) {
            wmNewsMaterial.setType((short) 1);
            saveRelativeInfoForContent(wmNewsMaterial, dto.getImages());
        }
        if (images != null) {
            wmNewsMaterial.setType((short) 0);
            saveRelativeInfoForContent(wmNewsMaterial, images);
        }
    }

    private void saveRelativeInfoForContent(WmNewsMaterial wmNewsMaterial, List<String> images) {
        Short i = 0;
        for (String s : images) {
            Integer materialId = wmMaterialMapper.findByUrl(s);
            wmNewsMaterial.setMaterialId(materialId);
            wmNewsMaterial.setOrd(i);
            wmNewsMaterialMapper.insert(wmNewsMaterial);
            i++;
        }
    }

    private void fillNews(WmNewsDto dto, WmNews wmNews, List<String> images) {

        StringBuilder image = new StringBuilder("");
        //从正文中获取图片
        String content = dto.getContent();
        JSONArray objects = JSON.parseArray(content);

        //处理images字段
        for (Object object : objects) {
            JSONObject json = JSONObject.parseObject(object.toString());
            if (json.getString("type").equals(WemediaContans.WM_NEWS_TYPE_IMAGE)) {
                images.add(json.getString("value").replace(fileServerUrl, ""));
            }
        }

        //处理type字段和image字段
        if (WemediaContans.WM_NEWS_AUTO_TYPE.equals(dto.getType())) {
            wmNews.setType((short) (images.size() < 1 ? 0 : images.size() > 2 ? 3 : 1));

            for (int i = 0; i < images.size(); i++) {
                if (i == (images.size() - 1)) {
                    image.append(images.get(i));
                } else {
                    image.append(images.get(i)).append(",");
                }
            }
        } else {
            int size = dto.getImages().size();
            for (int i = 0; i < size; i++) {
                if (i == size - 1) {
                    image.append(dto.getImages().get(i));
                } else {
                    image.append(dto.getImages().get(i)).append(",");
                }
            }
        }
        wmNews.setImages(image.toString());
        wmNews.setSubmitedTime(new Date());


    }


}
